package com.payment.service.alast.impl;

import com.payment.config.datasource.DataSource;
import com.payment.config.dto.StringOutputConstant;
import com.payment.entity.alast.common.ServicePlanOrderRecord;
import com.payment.entity.alast.resultconfirm.response.ResponseResultConfirm;
import com.payment.entity.alast.stripe.StripePaymentTransaction;
import com.payment.entity.payresults.PayPalNotificationPaymentResults;
import com.payment.entity.payresults.PayPalPaymentResults;
import com.payment.entity.payresults.WeiXinNotificationPaymentResults;
import com.payment.mapper.alast.PaymentAndResultMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
/**
 * 辅助公共逻辑处理业务方法类
 * @author lm
 * @date 2020/8/12 10:45
 */

public class AssistComLogicServiceImpl {
    private static Logger logger = Logger.getLogger(AssistComLogicServiceImpl.class);
    @Resource
    PaymentAndResultMapper paymentAndResultMapper;

    /**
     * payPal的webHook流水记录入库：payment_transaction_paypal_webhook_t
     *
     * @param paypal_id
     * @param state
     * @param payId
     * @param payment_mode
     * @param protection_eligibility
     * @param protection_eligibility_type
     * @param parent_payment
     * @param mount
     * @param currency
     * @param subtotal
     * @param value
     * @param currencys
     */
    @DataSource(name = "second")
    public Integer insertPayPalWebHookResults(String paypal_id, String state, String payId, String
            payment_mode, String protection_eligibility, String protection_eligibility_type, String parent_payment, String
                                                      mount, String currency, String subtotal, String value, String currencys) {
        PayPalPaymentResults results = new PayPalPaymentResults();
        results.setPaypal_id(paypal_id);
        results.setState(state);
        results.setInvoice_number(payId);
        results.setPayment_mode(payment_mode);
        results.setProtection_eligibility(protection_eligibility);
        results.setProtection_eligibility_type(protection_eligibility_type);
        results.setParent_payment(parent_payment);
        results.setTotal(mount);
        results.setCurrency(currency);
        results.setSubtotal(subtotal);
        results.setTransaction_fee(value);
        results.setTransaction_fee_currency(currencys);
        return paymentAndResultMapper.insertPayPalWebHookResults(results);
    }

    /**
     * 查询微信记录是否存在
     *
     * @param out_trade_no
     * @param transaction_id
     * @return
     */
    public Integer findCountByOutTradeNo(String out_trade_no, String transaction_id) {
        return paymentAndResultMapper.findWeiXinResultCount(out_trade_no, transaction_id);
    }

    /**
     * 微信支付流水记录入库：payment_transaction_weixin_t
     *
     * @param transaction_id
     * @param fee_type
     * @param out_trade_no
     * @param result_code
     * @param return_code
     * @param total_fee
     */
    @DataSource(name = "second")
    public Integer insertWeiXinResults(String out_trade_no, String transaction_id, String total_fee, String fee_type, String result_code, String return_code) {

        WeiXinNotificationPaymentResults results = new WeiXinNotificationPaymentResults();
        results.setOutTradeNo(out_trade_no);
        results.setTransactionId(transaction_id);
        results.setTotalFee(total_fee);
        results.setFeeType(fee_type);
        results.setResultCode(result_code);
        results.setReturnCode(return_code);
        return paymentAndResultMapper.insertWeiXinResults(results);
    }


    /**
     * 更新支付订单记录数据：service_plan_order_record_t
     *
     * @param payId
     * @param payUnit
     * @param currency
     * @param settlePrice
     * @param transactionId
     * @param payType
     * @param payRst
     * @param payAccount
     * @return
     */
    public Integer updateOrderRecordT(String payId, String payUnit, String payAmount, String currency, String
            settlePrice, String transactionId, String payType, String payRst, String payAccount) {
        ServicePlanOrderRecord record = new ServicePlanOrderRecord();
        record.setPayId(payId);
        record.setPayAmount(payAmount);
        record.setPayCurrency(currency);
        record.setPayUnit(payUnit);
        record.setSettlePrice(settlePrice);
        record.setTransactionId(transactionId);
        record.setPayType(payType);
        record.setPayRst(payRst);
        record.setPayAccount(payAccount);
        record.setPayStatus("1");
        record.setPayResultDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return paymentAndResultMapper.updateOrderRecordT(record);
    }

    /**
     * payPal支付流水记录入库：payment_transaction_paypal_ipn_t
     *
     * @param mc_gross
     * @param invoice
     * @param payment_status
     * @param mc_currency
     * @param txn_id
     * @param protection_eligibility
     * @param address_status
     * @param payer_id
     * @param address_street
     * @param payment_date
     * @param charset
     * @param address_zip
     * @param first_name
     * @param mc_fee
     * @param address_country_code
     * @param address_name
     * @param notify_version
     * @param custom
     * @param payer_status
     * @param business
     * @param address_country
     * @param address_city
     * @param quantity
     * @param verify_sign
     * @param payer_email
     * @param payment_type
     * @param last_name
     * @param address_state
     * @param receiver_email
     * @param payment_fee
     * @param receiver_id
     * @param txn_type
     * @param item_name
     * @param item_number
     * @param residence_country
     * @param receipt_id
     * @param transaction_subject
     * @param payment_gross
     * @param ipn_track_id
     * @return
     */
    @DataSource(name = "second")
    public Integer insertPayPalIpnResultsT(String mc_gross, String invoice, String payment_status, String
            mc_currency, String txn_id, String protection_eligibility, String address_status, String payer_id, String
                                                   address_street, String payment_date, String charset, String address_zip, String first_name, String
                                                   mc_fee, String address_country_code, String address_name, String notify_version, String custom, String
                                                   payer_status, String business, String address_country, String address_city, String quantity, String
                                                   verify_sign, String payer_email, String payment_type, String last_name, String address_state, String
                                                   receiver_email, String payment_fee, String receiver_id, String txn_type, String item_name, String
                                                   item_number, String residence_country, String receipt_id, String transaction_subject, String
                                                   payment_gross, String ipn_track_id) {

        PayPalNotificationPaymentResults results = new PayPalNotificationPaymentResults();
        results.setAmount(mc_gross);
        results.setInvoice(invoice);
        results.setPaymentStatus(payment_status);
        results.setMcCurrency(mc_currency);
        results.setTxnId(txn_id);
        results.setProtection_eligibility(protection_eligibility);
        results.setAddress_status(address_status);
        results.setPayer_id(payer_id);
        results.setAddress_street(address_street);
        results.setPayment_date(payment_date);
        results.setCharset(charset);
        results.setAddress_zip(address_zip);
        results.setFirst_name(first_name);
        results.setMc_fee(mc_fee);
        results.setAddress_country_code(address_country_code);
        results.setAddress_name(address_name);
        results.setNotify_version(notify_version);
        results.setCustom(custom);
        results.setPayer_status(payer_status);
        results.setBusiness(business);
        results.setAddress_country(address_country);
        results.setAddress_city(address_city);
        results.setQuantity(quantity);
        results.setVerify_sign(verify_sign);
        results.setPayer_email(payer_email);
        results.setPayment_type(payment_type);
        results.setLast_name(last_name);
        results.setAddress_state(address_state);
        results.setReceiver_email(receiver_email);
        results.setPayment_fee(payment_fee);
        results.setReceipt_id(receiver_id);
        results.setTxn_type(txn_type);
        results.setItem_name(item_name);
        results.setItem_number(item_number);
        results.setResidence_country(residence_country);
        results.setReceipt_id(receipt_id);
        results.setTransaction_subject(transaction_subject);
        results.setPayment_gross(payment_gross);
        results.setIpn_track_id(ipn_track_id);

        return paymentAndResultMapper.insertPayPalIpnResultsT(results);

    }

    /**
     * payPal申诉退款等流水记录入库：payment_transaction_paypal_ipn_reversed_t
     *
     * @param mc_gross
     * @param invoice：领科自己的支付单号
     * @param payment_status
     * @param mc_currency
     * @param txn_id：申诉或者退款时有又的新的流水号
     * @param parent_txn_id：是指支付时的流水号
     * @param protection_eligibility
     * @param address_status
     * @param payer_id
     * @param address_street
     * @param payment_date
     * @param charset
     * @param address_zip
     * @param first_name
     * @param mc_fee
     * @param address_country_code
     * @param address_name
     * @param notify_version
     * @param custom
     * @param payer_status
     * @param business
     * @param address_country
     * @param address_city
     * @param quantity
     * @param verify_sign
     * @param payer_email
     * @param payment_type
     * @param last_name
     * @param address_state
     * @param receiver_email
     * @param payment_fee
     * @param receiver_id
     * @param txn_type
     * @param item_name
     * @param item_number
     * @param residence_country
     * @param receipt_id
     * @param transaction_subject
     * @param payment_gross
     * @param ipn_track_id
     * @return
     */
    @DataSource(name = "second")
    public Integer insertPayPalReversedT(String mc_gross, String invoice, String payment_status, String
            mc_currency, String txn_id, String parent_txn_id, String protection_eligibility, String address_status, String
                                                 payer_id, String address_street, String payment_date, String charset, String address_zip, String
                                                 first_name, String mc_fee, String address_country_code, String address_name, String notify_version, String
                                                 custom, String payer_status, String business, String address_country, String address_city, String
                                                 quantity, String verify_sign, String payer_email, String payment_type, String last_name, String
                                                 address_state, String receiver_email, String payment_fee, String receiver_id, String txn_type, String
                                                 item_name, String item_number, String residence_country, String receipt_id, String transaction_subject, String
                                                 payment_gross, String ipn_track_id) {

        PayPalNotificationPaymentResults results = new PayPalNotificationPaymentResults();
        results.setAmount(mc_gross);
        results.setInvoice(invoice);
        results.setPaymentStatus(payment_status);
        results.setMcCurrency(mc_currency);
        results.setTxnId(txn_id);
        results.setParent_txn_id(parent_txn_id);
        results.setProtection_eligibility(protection_eligibility);
        results.setAddress_status(address_status);
        results.setPayer_id(payer_id);
        results.setAddress_street(address_street);
        results.setPayment_date(payment_date);
        results.setCharset(charset);
        results.setAddress_zip(address_zip);
        results.setFirst_name(first_name);
        results.setMc_fee(mc_fee);
        results.setAddress_country_code(address_country_code);
        results.setAddress_name(address_name);
        results.setNotify_version(notify_version);
        results.setCustom(custom);
        results.setPayer_status(payer_status);
        results.setBusiness(business);
        results.setAddress_country(address_country);
        results.setAddress_city(address_city);
        results.setQuantity(quantity);
        results.setVerify_sign(verify_sign);
        results.setPayer_email(payer_email);
        results.setPayment_type(payment_type);
        results.setLast_name(last_name);
        results.setAddress_state(address_state);
        results.setReceiver_email(receiver_email);
        results.setPayment_fee(payment_fee);
        results.setReceipt_id(receiver_id);
        results.setTxn_type(txn_type);
        results.setItem_name(item_name);
        results.setItem_number(item_number);
        results.setResidence_country(residence_country);
        results.setReceipt_id(receipt_id);
        results.setTransaction_subject(transaction_subject);
        results.setPayment_gross(payment_gross);
        results.setIpn_track_id(ipn_track_id);

        return paymentAndResultMapper.insertPayPalReversedT(results);
    }

    /**
     * 根据payId查询数据库里面存在几条数据
     *
     * @param payId
     * @return
     */
    @DataSource(name = "second")
    public Integer findCountByNo(String payId) {

        //查询out_trade_no在数据库有几条记录
        Integer recordCount = paymentAndResultMapper.findPayIdCount(payId);
        Integer payIdCount;

        if (recordCount <= 0) {
            //查询out_trade_no在数据库有几条记录
            Integer histCount = paymentAndResultMapper.findPayIdHistCount(payId);
            if (histCount <= 0) {
                payIdCount = 0;
            } else {
                payIdCount = histCount;
            }
        } else {
            payIdCount = recordCount;
        }
        return payIdCount;
    }

    /**
     * 将ipn的字符串按照&分割，然后将有param但是没有value值的用0补全，然后将param和value以键值对的方式存到map里面去
     *
     * @param resStr
     * @return
     */
    @DataSource(name = "second")
    public Map<String, String> StringToMap(String resStr) {

        Map<String, String> map = new HashMap<String, String>();

        try {

            String[] outerSplit = resStr.split("&");

            for (int i = 0; i < outerSplit.length; i++) {

                if (outerSplit[i].split("=").length == 1) {
                    outerSplit[i] = outerSplit[i] + "0";
                }
                String[] innerSplit = outerSplit[i].split("=");
                map.put(innerSplit[0], URLDecoder.decode(innerSplit[1], "UTF-8"));
            }

        } catch (Exception e) {
            logger.info("ipn的字符串按照&分割转map时发生异常：" + e);
        }
        logger.info("ipn的字符串转map：" + map);
        return map;
    }

    /**
     * 根据参数返回需要的响应内容
     *
     * @param recordList
     * @return
     */
    public ResponseResultConfirm responseRecord(List<ServicePlanOrderRecord> recordList, String payRst, String date) {

        ResponseResultConfirm response = null;

        if (null != recordList && !recordList.isEmpty()) {

            for (ServicePlanOrderRecord record : recordList) {
                response = new ResponseResultConfirm();
                response.setPartnerCode(record.getPartnerCode());
                response.setPayRst(payRst);
                response.setPayId(record.getPayId());
                if ("USD".equalsIgnoreCase(record.getPayCurrency())) {
                    response.setPayAmount("$" + record.getPayAmount());
                } else if ("EUR".equalsIgnoreCase(record.getPayCurrency())) {
                    response.setPayAmount("€" + record.getPayAmount());
                } else {
                    response.setPayAmount("￥" + record.getPayAmount());
                }
                response.setServicePlanShowName(record.getServicePlanShowName());
                response.setOrderPeriod(setOrderPeriod(record.getPackageType(), record.getOrderPeriod()));
                response.setPackageType(record.getPackageType());
                if (StringUtils.isNotBlank(record.getPayResultDate())) {
                    response.setPayResultDate(record.getPayResultDate());
                } else {
                    response.setPayResultDate(date);
                }
            }
        }
        return response;
    }

    /**
     * 标准化输出orderPeriod
     * 按照packageType的值来判断
     * 特殊处理季度，半年，4个月，18个月，2年
     *
     * @param packageType
     * @param orderPeriod
     * @return
     */
    public String setOrderPeriod(String packageType, String orderPeriod) {
        String result = "";
        //原始：周期+单位
        if (StringOutputConstant.CODE_ZERO.equals(packageType) || StringOutputConstant.CODE_ONE.equals(packageType) || StringOutputConstant.CODE_TWO.equals(packageType) || StringOutputConstant.CODE_FIVE.equals(packageType)) {
            result = orderPeriod;
        } //特殊处理季度套餐：周期*3+单位（月）
        else if (StringOutputConstant.CODE_THREE.equals(packageType)) {
            result = String.valueOf(Integer.parseInt(orderPeriod) * 3);
        }  //特殊处理半年套餐：周期*6+单位（月）
        else if (StringOutputConstant.CODE_FOUR.equals(packageType)) {
            result = String.valueOf(Integer.parseInt(orderPeriod) * 6);
        } //特殊处理4个月套餐：周期*4+单位（月）
        else if (StringOutputConstant.CODE_SIX.equals(packageType)) {
            result = String.valueOf(Integer.parseInt(orderPeriod) * 4);
        } //特殊处理18个月套餐：周期*18+单位（月）
        else if (StringOutputConstant.CODE_SEVEN.equals(packageType)) {
            result = String.valueOf(Integer.parseInt(orderPeriod) * 18);
        } //特殊处理2年套餐：周期*2+单位（年）
        else if (StringOutputConstant.CODE_EIGHT.equals(packageType)) {
            result = String.valueOf(Integer.parseInt(orderPeriod) * 2);
        } //原始：周期+单位
        else {
            result = orderPeriod;
        }
        return result;
    }

    /**
     * ipn成功支付记录异常入库
     *
     * @param mount
     * @param payId
     * @param paymentStatus
     * @param currency
     * @param txnId
     * @param business
     * @param payer_email
     * @param resStr
     * @return
     */
    public Integer insertExceptionIpnStr(String mount, String payId, String paymentStatus, String currency, String txnId, String business, String payer_email, String resStr) {
        PayPalNotificationPaymentResults results = new PayPalNotificationPaymentResults();
        results.setAmount(mount);
        results.setInvoice(payId);
        results.setPaymentStatus(paymentStatus);
        results.setMcCurrency(currency);
        results.setTxnId(txnId);
        results.setBusiness(business);
        results.setPayer_email(payer_email);
        results.setIpnStr(resStr);
        return paymentAndResultMapper.insertIpnStr(results);
    }

    /**
     * 入库：payment_transaction_stripe_t
     *
     * @param payId
     * @param mount
     * @param currency
     * @param receiptEmail
     * @param customer
     * @param txnId
     * @param invoice
     * @param status
     * @param stripeStr
     * @return
     */
    public Integer insertStripePayment(String payId, String mount, String currency, String receiptEmail, String customer, String txnId, String invoice, String status, String pmId, String stripeStr) {
        StripePaymentTransaction result = new StripePaymentTransaction();
        result.setDescription(payId);
        result.setMount(mount);
        result.setCurrency(currency);
        result.setReceiptEmail(receiptEmail);
        result.setCustomer(customer);
        result.setTxnId(txnId);
        result.setInvoice(invoice);
        result.setStatus(status);
        result.setPmId(pmId);
        result.setStripeStr(stripeStr);
        return paymentAndResultMapper.insertStripePayment(result);

    }

    /**
     * 更新了一条之后要去订单记录表中添加一条记录了  service_plan_order_record_t
     *
     * @param recordList
     * @param txnId
     * @param invoice
     * @return
     */
    public Integer insertRecord(List<ServicePlanOrderRecord> recordList, String txnId, String invoice) {
        Integer c = 0;
        for (ServicePlanOrderRecord re : recordList) {
            ServicePlanOrderRecord records = new ServicePlanOrderRecord();
            records.setPayId(re.getPayId());
            records.setPayRst(re.getPayRst());
            records.setPayType(re.getPayType());
            records.setPayAccount(re.getPayAccount());
            records.setTransactionId(txnId);
            records.setDeviceCode(re.getDeviceCode());
            records.setOrderNo(invoice);
            records.setPartnerCode(re.getPartnerCode());
            records.setPartnerName(re.getPartnerName());
            records.setServicePlanShowName(re.getServicePlanShowName());
            records.setServicePlanCode(re.getServicePlanCode());
            records.setPackageName(re.getPackageName());
            records.setPackageCode(re.getPackageCode());
            records.setPackageType(re.getPackageType());
            records.setOrderPeriod(re.getOrderPeriod());
            records.setPayAmount(re.getPayAmount());
            records.setPayCurrency(re.getPayCurrency());
            records.setPayUnit(re.getPayUnit());
            records.setSettlePrice(re.getSettlePrice());
            records.setPayStatus("1");
            records.setTerminal(re.getTerminal());
            records.setMark(re.getMark());
            records.setPayResultDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            c = paymentAndResultMapper.insertRecord(records);
        }
        return c;
    }
}
